module ask_dem (
    input wire clk,
    input wire rst_n,
    input wire [11: 0] in,
    input wire in_valid,
    output reg dout,
    output reg write
);
    
    localparam SAMPLE_RATE = 10e6;
    localparam SAMPLE_PER_SYMBOL = 100;
    localparam THRESHOLD = 1000;
    localparam HIGH_CONTINOUS_LIM = 4;
    localparam LOW_CONTINOUS_LIM = 4;

    /* 维护一个三段式状态机，时时刻刻进行数据解调输出 */
    // 状态参量 解调计数
    // 输入参量 输入信号幅值
    // 输出参量 解调结果 
    localparam EMPTY = 0;
    localparam HIGH_START = 1;
    localparam HIGH_REACH = HIGH_CONTINOUS_LIM;
    localparam LOW_START = 15;
    localparam LOW_REACH = 15 - LOW_CONTINOUS_LIM;

    wire [11: 0] in_abs = (in[11] == 0) ? in : (~in) + 1; 
    wire in_abs_high = in_abs > 1000; 
    reg [3: 0] status;
    reg [3: 0] next_status;
    reg demod;

    always @(posedge clk) begin
        if (~rst_n) 
            status <= EMPTY;
        else 
            status <= next_status;
    end

    always @(status, in_abs) begin
        case (in_abs_high)
            1'b1: begin
                if (status >= HIGH_START && status < HIGH_REACH) begin
                    next_status = status + 1;
                end else if (status == HIGH_REACH) begin
                    next_status = status;
                end else begin
                    next_status = HIGH_START; 
                end
            end
            1'b0: begin
                if (status > LOW_REACH && status <= LOW_START) begin
                    next_status = status - 1;
                end else if (status == LOW_REACH) begin
                    next_status = status;
                end else begin
                    next_status = LOW_START; 
                end
            end 
        endcase
    end

    // 注意，这里是延迟了一个tick输出结果的，因为这个是流式的过程，所以影响不会很大
    always @(posedge clk) begin
        if (~rst_n)
            demod <= 0;
        else begin
            case (status)
                LOW_REACH: demod <= 0; 
                HIGH_REACH: demod <= 1;
                default: demod <= demod;
            endcase
        end
    end

    localparam PHASE_INC = 17'h10000 / SAMPLE_PER_SYMBOL;
    reg [16:0] phase;
    reg [16:0] phase_to_inc;
    reg [1:0] demod_buff;
    always @(posedge clk) begin
        if(~rst_n) begin
            demod_buff <= 0;
            phase <= 17'h0000;
        end else begin
            if (in_valid) begin
                demod_buff <= {demod_buff[0], demod};
                phase_to_inc = PHASE_INC;
                // 如果 demod 发生变化（上升沿/下降沿），如果此时相位恰好为 1/2
                // 最大相位（0x8000），则说明当前抽样位置在正中间。若不是则说明
                // 当前抽样位置有所偏移，应该通过额外的相位累加以进行调整
                if (demod_buff[1] ^ demod_buff[0]) begin
                    if (phase < (17'h8000 - (PHASE_INC >> 1))) begin
                        phase_to_inc = phase_to_inc + (PHASE_INC >> 1);
                    end else begin
                        phase_to_inc = phase_to_inc - (PHASE_INC >> 1);
                    end
                end
                // 相位累加器发生溢出时即抽样时刻
                if (phase + phase_to_inc > 17'h10000) begin
                    phase <= (phase + phase_to_inc) & 17'hffff;
                    // 输出 write 脉冲，赋值 dout
                    write <= 1;
                    dout <= demod;
                end else begin
                    phase <= (phase + phase_to_inc);
                    write <= 0;
                end
            end
        end
    end



endmodule